/*
* Copyright 2010 Competentum group
*
* Licensed under the GNU General Public License, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.gnu.org/licenses/gpl.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.competentum.builders
{
	import com.competentum.vos.AbstractItemVO;
	import com.competentum.vos.BindVO;
	import com.competentum.vos.EmployeeVO;
	import com.competentum.vos.ProjectVO;
	import com.competentum.windows.Scope;
	import com.competentum.lib.data.builders.AbstractDataBuilder;
	import com.competentum.lib.data.vo.UniqueVO;
	
	import mx.collections.ArrayCollection;

	/**
	 * This Builder holds all Bind objects and provides us with methods to create and handle them 
	 * @author Demidov
	 */	
	public class BindsBuilder extends AbstractDataBuilder
	{
		public static const TYPE:String = "BindsBuilder";
		
		private var scope:Scope;
		
		override public function get global():Boolean
		{
			return false;
		}
		
		public function BindsBuilder(scope:Scope)
		{
			super(TYPE);
			this.scope = scope;
		}
		
		public function createItemFromXML(xml:XML, addToArray:Boolean = true):AbstractItemVO
		{
			var employeesBuilder:AbstractDataBuilder = DataBuildersFactory.getDataBuilder(EmployeesBuilder.TYPE, scope);
			var projectsBuilder:AbstractDataBuilder = DataBuildersFactory.getDataBuilder(ProjectsBuilder.TYPE, scope);
			return createItem(employeesBuilder.getItemByUid(xml.@employee) as AbstractItemVO, projectsBuilder.getItemByUid(xml.@project) as AbstractItemVO, xml.@hoursReserved, addToArray);
		}
		
		public function createItem(employee:AbstractItemVO, project:AbstractItemVO, hoursReserved:Number, addToArray:Boolean = true):BindVO
		{
			var bind:BindVO = new BindVO();
			bind.employee = employee;
			bind.project = project;
			bind.hoursReserved = hoursReserved;
			bind.scope = scope;
			if (addToArray)
				addItem(bind);
			
			return bind;
		}
		
		/**
		 * remove bind 
		 * @param bind
		 * 
		 */		
		override public function removeItem(item:UniqueVO):void
		{
			var bind:BindVO = item as BindVO;
			bind.notifyHolders();
			super.removeItem(item);
		}
		
		/**
		 * Returns a Vector with all binds related to given employee or project vo. 
		 * @param item
		 * @return 
		 * 
		 */		
		public function getBindingsListForItem(item:AbstractItemVO):Vector.<BindVO>
		{
			var answer:Vector.<BindVO> = new Vector.<BindVO>();
			for each (var bind:BindVO in itemsVector)
			{
				if ((bind.employee.uid == item.uid && item is EmployeeVO) || (bind.project.uid == item.uid && item is ProjectVO))
				{
					answer.push(bind);
				}
			}
			
			return answer;
		}
		
		/**
		 * Return all hours reserved of employee or project
		 * */
		public function getTotalReservedHours(item:AbstractItemVO):Number
		{
			var result:Number = 0;
			var binds:Vector.<BindVO> = getBindingsListForItem(item);
			for (var i:int = 0; i < binds.length; i ++ )
			{
				result += binds[i].hoursReserved;
			}
			return result;
		}
		
		/**
		 * Look for a bind binded to the same employee and project  
		 * @param bind
		 * @return 
		 * 
		 */		
		public function findSameBind(bind:BindVO):BindVO 
		{
			for each (var currentBind:BindVO in itemsVector) 
			{
				if (currentBind.employee.uid == bind.employee.uid 
					&& currentBind.project.uid == bind.project.uid) {
					return currentBind;
				}
			}
			
			return null;
		}
		
		public function getBindForPair(employee:EmployeeVO, project:ProjectVO):BindVO
		{
			var binds:Vector.<BindVO> = getBindingsListForItem(employee);
			for each (var bind:BindVO in binds)
			{
				if (bind.project.uid == project.uid)
				{
					return bind;
				}
			}
			return null;
		}
		
		override public function toString():String
		{
			var result:String = '';
			for (var i:int = 0; i < itemsCount; i ++ )
			{
				result += getItemByIndex(i);
				if (i < itemsCount - 1)
				{
					result += ', ';
				}
			}
			return result;
		}
	}
}